package cc.cix.hq.common.validate.code.service.impl;

import cc.cix.hq.common.core.entity.constant.HqConstant;
import cc.cix.hq.common.core.exception.HqException;
import cc.cix.hq.common.upload.service.IRedisService;
import cc.cix.hq.common.validate.code.properties.ValidateCodeProperties;
import cc.cix.hq.common.validate.code.service.IValidateCodeService;
import cn.hutool.core.img.ImgUtil;
import com.wf.captcha.GifCaptcha;
import com.wf.captcha.SpecCaptcha;
import com.wf.captcha.base.Captcha;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.util.HashMap;
import java.util.Map;

/**
 * 验证码服务
 *
 * @author zhenghuajing
 */
@Service
@RequiredArgsConstructor
public class ValidateCodeServiceImpl implements IValidateCodeService {

    private final ValidateCodeProperties validateCodeProperties;
    private final IRedisService redisService;

    @Override
    public Map<String, String> create(HttpServletRequest request) {
        HttpSession session = request.getSession();
        String key = session.getId();

        Captcha captcha = createCaptcha(validateCodeProperties);
        String codeKey = HqConstant.CODE_PREFIX + key;
        String codeValue = StringUtils.lowerCase(captcha.text());
        redisService.set(codeKey, codeValue, validateCodeProperties.getTime().getSeconds());

        Map<String, String> map = new HashMap<>(2);
        map.put("key", key);
        map.put("img", captcha.toBase64("data:image/png;base64,"));
        return map;
    }

    @Override
    public void check(String key, String value) throws HqException {
        String codeKey = HqConstant.CODE_PREFIX + key;
        Object codeInRedis = redisService.get(codeKey);

        if (codeInRedis == null) {
            throw new HqException("验证码已过期");
        }

        if (!StringUtils.equalsIgnoreCase(value, String.valueOf(codeInRedis))) {
            throw new HqException("验证码不正确");
        }

        // 校验成功删除验证码
        redisService.del(codeKey);
    }

    private Captcha createCaptcha(ValidateCodeProperties code) {
        Captcha captcha;
        if (StringUtils.equalsIgnoreCase(code.getType(), ImgUtil.IMAGE_TYPE_GIF)) {
            captcha = new GifCaptcha(code.getWidth(), code.getHeight(), code.getLength());
        } else {
            captcha = new SpecCaptcha(code.getWidth(), code.getHeight(), code.getLength());
        }
        captcha.setCharType(code.getCharType());
        return captcha;
    }

}
